Virtual memory is used to minimize the physical memory of data processing systems or computers. The physical memory of a computer is typically Random Access Memory (RAM) and serves as a primary storage for the Central Processing Unit (CPU). RAM is typically fast enough to communicate with the CPU. Unfortunately, RAM is relatively expensive. With virtual memory, a relatively inexpensive storage device with a large capacity is utilized. Typically, this storage device is a fixed (or hard) disk.
With virtual memory, the computer has the capability of addressing a memory space much larger than what is available on RAM. Information. (data, code, etc.) is moved between the fixed disk and RAM. A virtual memory manager controls the moving of information between the fixed disk and RAM.
There are several strategies employed in virtual memory management. One such strategy is to preload all the information for an application program into RAM. After the program is initialized, that information which is used only for initialization is "discarded" from RAM. Another strategy is to load information into RAM on demand (instead of preloading the information). The information is transferred in blocks referred to as pages or segments.
Still another strategy involves determining what information has not been referenced by the CPU for some amount of time. When the amount of requested RAM exceeds the amount of available RAM, then the least recently used information is swapped from RAM to the fixed disk. This creates space in RAM, wherein the requested information can be swapped in from the fixed disk to the empty space in RAM. This latter strategy is utilized by an operating system known as OS/2 (OS/2 is a trademark of International Business Machines Corporation.)
An "ager" daemon thread is employed by the virtual memory manager to anticipate a next request from memory by determining which information in RAM is suitable for swapping out to fixed disk. Daemon threads are processes that execute in the background, so that a user typically is not aware of the thread. The ager runs in response to a request from memory. The ager is able to determine if information in RAM has been recently referenced through the use of a page table. The page table has entries for the pages (or blocks of information) contained in RAM. When a request from memory is made, the ager marks a number of pages as "clean" in the page table entries, in order to establish a reference. When an executing program accesses a page, the entry for that page is marked, thereby indicating that a reference to that page has been made. On subsequent runs of the ager, the least recently used pages are linked to an idle list. Pages on the idle list are candidates for swapping out from RAM to fixed disks. Pages on the idle list can be reclaimed whenever those pages are accessed by a running thread (or executing program). Reclaiming pages from the idle list (which pages are still in RAM) is more efficient than reloading the pages from fixed disk into RAM.
The prior art attempts to maintain the idle list at a size of 40 pages. This is accomplished by having the ager run at various priorities, depending on the size of the idle list. The following table illustrates the number of pages that are on the idle list (within a range of pages defined by a minimum and a maximum) and the respective priority of the ager:
______________________________________ Min Idle Max Idle Priority ______________________________________ 0 10 TIME.sub.-- CRITICAL 11 20 REGULAR 21 30 REGULAR 31 40 IDLE-- ______________________________________
Thus, if the idle list contains few or no pages, then the priority of the ager is TIME.sub.-- CRITICAL. Having this high priority causes the ager to run in order to fill up the idle list. If the idle list contains an intermediate number of pages, then the priority of the ager is REGULAR. If the idle list contains a number of pages that is close to forty, then the priority of the ager is IDLE. With an IDLE priority, the ager need only run during the CPU's idle cycles because the idle list is either full or almost full.
A problem arises in computers that have small memory configurations or overcommitted systems. This is because the ager runs to maintain the idle list at a fixed size. However, running the ager utilizes a large percentage of CPU time just to maintain the size of the idle list. This interferes with, and may even preempt, threads doing actual work. In fact, in some instances (for example in regular and server classes) user threads or processes which may not need memory to run are preempted by the ager. Thus, the ager executes to anticipate the next request for memory, when the user thread does not need memory and is unable to run because of the ager.
Another problem is that the prior art ager processes do not take into account the number of resident pages in the system. The ager is set up at initialization based upon the amount of physical memory at that time. However, after initialization, the number of swappable pages in the system can be reduced. Such a change could come about, for example, by adding software which allocates resident memory. Such software could be a LAN or else simply running a program that allocates resident memory. Because the size of the idle list is fixed, the ager compensates by running more often in order to stay abreast of the reduced number of swappable pages in the system. Again, the frequent running of the ager utilizes CPU time.